home *** CD-ROM | disk | FTP | other *** search
- unit Format;
-
- interface
-
- uses WinTypes, WinProcs;
-
- const
- { Format capacities }
- DF_360K = 0;
- DF_12M = 1;
- DF_720K = 2;
- DF_14M = 3;
- DF_28M = 4;
- DF_Unknown = 5;
-
- function AbsRead (Drive: Byte; NumSectors, StartSec: Integer;
- Buffer: Pointer): Integer;
- function AbsWrite (Drive: Byte; NumSectors, StartSec: Integer;
- Buffer: Pointer): Integer;
- function GetMediaType (Drive: Byte): Integer;
- function LockVolume (Drive: Byte): Integer;
- function UnLockVolume (Drive: Byte): Integer;
-
- implementation
-
- type
- DiskType = record
- spc: Byte; { sectors per cluster }
- rde: Integer; { number of root-dir entries }
- sec: Integer; { total number of sectors }
- med: Byte; { media descriptor }
- spf: Integer; { number of sectors per FAT }
- spt: Integer; { sectors per track }
- end;
-
- const
- { This array maps a logical drive type to a list of }
- { parameters for that drive. Assumptions: }
- { Bytes per sector = 512 Reserved sectors = 1 }
- { Number of FATS = 2 Heads = 2 }
- { Hidden sectors = 0 Tracks = 80 except 40 for 1st }
-
- DiskTypes: array [0..4] of DiskType = (
-
- (spc:2; rde:112; sec: 720; med:$FD; spf:2; spt: 9), { 360 K }
- (spc:1; rde:224; sec:2400; med:$F9; spf:7; spt:15), { 1.2 M }
- (spc:2; rde:112; sec:1440; med:$F9; spf:3; spt: 9), { 720 K }
- (spc:1; rde:224; sec:2880; med:$F0; spf:9; spt:18), { 1.4 M }
- (spc:2; rde:240; sec:5760; med:$F0; spf:9; spt:36)); { 2.8 M }
-
- type
- PBootSector = ^BootSector;
- BootSector = record
- bsJump: array [0..2] of Byte; { 00 E9 XX XX or EB XX 90 }
- bsOemName: array [0..7] of Char; { 03 OEM name and version }
- bsBytesPerSec: Integer; { 0b bytes per sector }
- bsSecPerClust: Byte; { 0d sectors per cluster }
- bsResSectors: Integer; { 0e number of reserved sectors }
- bsFATs: Byte; { 10 number of file allocation tables }
- bsRootDirEnts: Integer; { 11 number of root-directory entries }
- bsSectors: Integer; { 13 total number of sectors }
- bsMedia: Byte; { 15 media descriptor }
- bsFATsecs: Integer; { 16 number of sectors per FAT }
- bsSecPerTrack: Integer; { 18 sectors per track }
- bsHeads: Integer; { 1a number of heads }
- bsHiddenSecs: LongInt; { 1c number of hidden sectors }
- bsHugeSectors: LongInt; { 20 number of sectors if bsSectors = 0 }
- bsDriveNumber: Byte; { 24 drive number }
- bsReserved1: Byte; { 25 reserved }
- bsBootSignature: Byte; { 26 extended boot signature }
- bsVolumeID: LongInt; { 27 volume ID number }
- bsVolumeLabel: array [0..10] of Char; { 2b volume label }
- bsFileSysType: array [0..7] of Char; { 36 file-system type }
- end;
-
- { Determine if we're running Windows 95 (or later) }
-
- function IsWindows95: Bool;
- var
- ver: LongInt;
- v: array [0..1] of Word absolute ver;
- begin
- ver := GetVersion;
- IsWindows95 := (Swap (v[0]) >= $35F) and (v[1] >= $700);
- end;
-
- { Read an absolute sector from a specified drive }
-
- function AbsRead (Drive: Byte; NumSectors, StartSec: Integer;
- Buffer: Pointer): Integer; assembler;
- asm
- mov al,Drive { AL = drive number for read }
- dec al { for compatability, A=1,... }
- mov cx,NumSectors { number of sectors to read }
- mov dx,StartSec { first sector to read }
- push ds { save DS prior to call }
- lds bx,Buffer { DS:BX = pointer to buffer }
- push bp { save stack frame }
- int 25h { do the absolute read }
- pop bx { pop and discard flags }
- pop bp { restore stack frame }
- pop ds { restore DS register }
- jc @@1 { branch if error }
- xor ax,ax { no error - return zero }
- @@1:
- end;
-
- { Write an absolute sector to a specified drive }
-
- function AbsWrite (Drive: Byte; NumSectors, StartSec: Integer;
- Buffer: Pointer): Integer; assembler;
- asm
- mov al,Drive { AL = drive number for write }
- dec al { for compatability, A=1,... }
- mov cx,NumSectors { number of sectors to write }
- mov dx,StartSec { first sector to write }
- push ds { save DS prior to call }
- lds bx,Buffer { DS:BX = pointer to buffer }
- push bp { save stack frame }
- int 26h { do the absolute write }
- pop bx { pop and discard flags }
- pop bp { restore stack frame }
- pop ds { restore DS register }
- jc @@1 { branch if error }
- xor ax,ax { no error - return zero }
- @@1:
- end;
-
- { Return the type of a given drive }
-
- function GetMediaType (Drive: Byte): Integer;
- var
- i: Integer;
- buff: array [0..511] of Byte;
- bs: BootSector absolute buff;
- begin
- GetMediaType := -1;
- { Read boot sector from disk }
- if AbsRead (Drive, 1, 0, @buff) = 0 then
- begin
- GetMediaType := DF_Unknown;
- for i := DF_360K to DF_28M do
- if bs.bsSectors = DiskTypes [i].sec then
- begin
- GetMediaType := i;
- Exit;
- end;
- end;
- end;
-
- function LUVolumePrim (Drive, Level, Op: Byte; Perm: Word): Integer; assembler;
- asm
- mov ax,$440D { specify generic IOCTL call }
- mov bl,Drive { get drive number in BL }
- dec bl { for compatability, A: = 1 }
- mov bh,Level { get lock level in BH }
- mov ch,8 { category 8 for drives }
- mov cl,Op { get lock/unlock physical }
- mov dx,Perm { get permissions word }
- int 21h { make the call }
- jc @@1 { branch if error }
- xor ax,ax { no error - so AX = 0 }
- @@1:
- end;
-
- function LockVolume (Drive: Byte): Integer;
- begin
- if IsWindows95 then
- begin
- LockVolume := -1;
- if LUVolumePrim (Drive, 0, $4B, 0) = 0 then
- if LUVolumePrim (Drive, 0, $4B, 4) = 0 then
- LockVolume := 0;
- end
- else LockVolume := 0;
- end;
-
- function UnLockVolume (Drive: Byte): Integer;
- begin
- if IsWindows95 then
- begin
- UnLockVolume := -1;
- if LUVolumePrim (Drive, 0, $6B, 0) = 0 then
- if LUVolumePrim (Drive, 0, $6B, 0) = 0 then
- UnLockVolume := 0;
- end
- else UnLockVolume := 0;
- end;
-
- end.